﻿//Mirco Töpfer

#region Usings

using System;
using System.Collections.Generic;
using pheidippides.common.Classes;
using pheidippides.logging.Classes;
using pheidippides.dataaccess.HelperClasses;
using pheidippides.configuration.Interfaces;
using System.Data;
using pheidippides.dataaccess.DatabaseStrukturEnumns;
using pheidippides.configuration.Classes;

#endregion

namespace pheidippides.dataaccess.Classes
{
    public static class VeranstaltungDataAccess
    {
        #region Public Static Methods

        /// <summary>
        /// Gets all.
        /// </summary>
        /// <returns></returns>
        public static List<VeranstaltungData> GetAll()
        {
            Logger.GetInstance().LogMessage("Hole alle Veranstaltungen aus der Datenbank", LogLevel.Debug);
            AccessDbSqlHelper dbHelper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));
            DataTable data = dbHelper.ExecuteQuery("Select * from " + DbEnumTables.veranstaltung);

            return GetVeranstaltungDataFromDataTable(data);
        }

        /// <summary>
        /// Saves the specified veranstaltung data.
        /// </summary>
        /// <param name="veranstaltungData">The veranstaltung data.</param>
        public static void Save(VeranstaltungData veranstaltungData)
        {
            String sqlCommand;

            if (CheckIfExists(veranstaltungData))
            {
                sqlCommand = "UPDATE " + DbEnumTables.veranstaltung + " SET " +
                             DbEnumVeranstaltung.datum + " = @" + DbEnumVeranstaltung.datum + ", " +
                             DbEnumVeranstaltung.name + " = @" + DbEnumVeranstaltung.name + ", " +
                             DbEnumVeranstaltung.notiz + " = @" + DbEnumVeranstaltung.notiz +
                             " WHERE " + DbEnumVeranstaltung.id + "= @" + DbEnumVeranstaltung.id;
            }
            else
            {
                sqlCommand = "INSERT INTO " + DbEnumTables.veranstaltung + " (" +
                             DbEnumVeranstaltung.datum + ", " +
                             DbEnumVeranstaltung.id + ", " +
                             DbEnumVeranstaltung.name + ", " +
                             DbEnumVeranstaltung.notiz +
                             ") VALUES (@" +
                             DbEnumVeranstaltung.datum + ", @" +
                             DbEnumVeranstaltung.id + ", @" +
                             DbEnumVeranstaltung.name + ", @" +
                             DbEnumVeranstaltung.notiz +
                             ")";
            }

            AccessDbSqlHelper helper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            helper.SetProperty(DbEnumVeranstaltung.datum, veranstaltungData.Datum);

            helper.SetProperty(DbEnumVeranstaltung.id, veranstaltungData.Id);
            helper.SetProperty(DbEnumVeranstaltung.name, veranstaltungData.Name);
            helper.SetProperty(DbEnumVeranstaltung.notiz, veranstaltungData.Notiz);

            helper.ExecuteNonQuery(sqlCommand);
        }

        /// <summary>
        /// Gets the specified id.
        /// </summary>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public static VeranstaltungData Get(Guid id)
        {
            Logger.GetInstance().LogMessage("Hole Veranstaltung " + id + " aus der Datenbank", LogLevel.Debug);

            AccessDbSqlHelper dbHelper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            dbHelper.SetProperty(DbEnumVeranstaltung.id, id);

            DataTable data =
                dbHelper.ExecuteQuery("Select * from " + DbEnumTables.veranstaltung + " where " +
                                      DbEnumVeranstaltung.id + " = @" + DbEnumVeranstaltung.id);

            if (data.Rows.Count > 1)
                throw new ApplicationException(
                    "Zu der angefragten Veranstaltung gibt es mehr als ein Objekt in der Datenbank!");
            if (data.Rows.Count == 0)
            {
                Logger.GetInstance().LogMessage("Es konnte in der Datenbank keine Veranstaltung mit der ID " + id + " gefunden werden!" , LogLevel.Warning);
                return null;
            }

            return GetVeranstaltungDataFromRow(data.Rows[0]);
        }

        /// <summary>
        /// Checks if exists.
        /// </summary>
        /// <param name="veranstaltungData">The veranstaltung data.</param>
        /// <returns></returns>
        public static bool CheckIfExists(VeranstaltungData veranstaltungData)
        {
            AccessDbSqlHelper helper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            helper.SetProperty("@" + DbEnumVeranstaltung.id, veranstaltungData.Id);

            DataTable data =
                helper.ExecuteQuery("select count(*) from " + DbEnumTables.veranstaltung + " where " +
                                    DbEnumVeranstaltung.id + " = @" + DbEnumVeranstaltung.id);

            if (Convert.ToInt32(data.Rows[0][0]) == 1)
                return true;

            if (Convert.ToInt32(data.Rows[0][0]) == 0)
                return false;

            throw new ApplicationException("Es sind mehr als eine erwartete Veranstaltung in der Datenbank.");
        }

        /// <summary>
        /// Deletes the specified veranstaltung data.
        /// </summary>
        /// <param name="veranstaltungData">The veranstaltung data.</param>
        public static void Delete(VeranstaltungData veranstaltungData)
        {

            
            //ToDo:Zerlegen auf die einzelnen Objekte und in die Business Logick

            Logger.GetInstance().LogMessage(
                "Löschen der Veranstaltung " + veranstaltungData.Name + " mit ID " + veranstaltungData.Id,
                LogLevel.Debug);
            AccessDbSqlHelper helper =
                new AccessDbSqlHelper(ConfigManager.GetInstance().GetConfigEnry(ConfigEntryName.DatabasePath));

            helper.SetProperty("@" + DbEnumVeranstaltung.id, veranstaltungData.Id);

            Logger.GetInstance().LogMessage("Löschen der erfassten Zeiten", LogLevel.Info);
            int result = helper.ExecuteNonQuery(
                "delete from " + DbEnumTables.erfasstezeit + " where " + DbEnumErfasstezeit.veranstaltung_fk +
                " = @" + DbEnumVeranstaltung.id);
            Logger.GetInstance().LogMessage(result + " Datensätze wurden gelöscht", LogLevel.Info);

            Logger.GetInstance().LogMessage("Löschen der vorhandenen Teilnehmer", LogLevel.Info);
            result =
                helper.ExecuteNonQuery(
                    "delete from " + DbEnumTables.teilnehmer + " where " + DbEnumTeilnehmer.veranstaltung_fk + " = @" +
                    DbEnumVeranstaltung.id);
            Logger.GetInstance().LogMessage(result + " Datensätze wurden gelöscht", LogLevel.Info);

            Logger.GetInstance().LogMessage("Löschen der vorhandenen Startklassen", LogLevel.Info);
            result =
                helper.ExecuteNonQuery(
                    "delete from " + DbEnumTables.startklasse + " where " + DbEnumStartklasse.veranstaltung_fk +
                    " = @" + DbEnumVeranstaltung.id);
            Logger.GetInstance().LogMessage(result + " Datensätze wurden gelöscht", LogLevel.Info);

            Logger.GetInstance().LogMessage("Löschen der eingetragenen Strecken", LogLevel.Info);
            result =
                helper.ExecuteNonQuery(
                    "delete from " + DbEnumTables.strecke + " where " + DbEnumStrecke.veranstaltung_fk + " = @" +
                    DbEnumVeranstaltung.id);
            Logger.GetInstance().LogMessage(result + " Datensätze wurden gelöscht", LogLevel.Info);

            Logger.GetInstance().LogMessage("Löschen der eingetragenen Runden", LogLevel.Info);
            result =
                helper.ExecuteNonQuery(
                    "delete from " + DbEnumTables.strecke_runde + " where " + DbEnumStreckeRunde.veranstaltung_fk +
                    " = @" + DbEnumVeranstaltung.id);
            Logger.GetInstance().LogMessage(result + " Datensätze wurden gelöscht", LogLevel.Info);

            Logger.GetInstance().LogMessage("Löschen der Veranstaltung", LogLevel.Info);
            result =
                helper.ExecuteNonQuery(
                    "delete from " + DbEnumTables.veranstaltung + " where " + DbEnumVeranstaltung.id + " = @" +
                    DbEnumVeranstaltung.id);
            Logger.GetInstance().LogMessage(result + " Datensätze wurden gelöscht", LogLevel.Info);

        }

        #endregion

        #region Private static Methods

        /// <summary>
        /// Gets the veranstaltung data from data table.
        /// </summary>
        /// <param name="data">The data.</param>
        /// <returns></returns>
        private static List<VeranstaltungData> GetVeranstaltungDataFromDataTable(DataTable data)
        {
            Logger.GetInstance().LogMessage("Erzeuge Teilnehmer aus Dataset", LogLevel.Debug);

            List<VeranstaltungData> veranstaltung = new List<VeranstaltungData>();

            foreach (DataRow row in data.Rows)
            {
                veranstaltung.Add(GetVeranstaltungDataFromRow(row));
            }

            return veranstaltung;
        }

        /// <summary>
        /// Gets the veranstaltung data from row.
        /// </summary>
        /// <param name="row">The row.</param>
        /// <returns></returns>
        private static VeranstaltungData GetVeranstaltungDataFromRow(DataRow row)
        {
            VeranstaltungData data = new VeranstaltungData();

            data.Id = new Guid((row[DbEnumVeranstaltung.id.ToString()].ToString()));

            if (row[DbEnumVeranstaltung.datum.ToString()] != DBNull.Value && !String.IsNullOrEmpty(row[DbEnumVeranstaltung.datum.ToString()].ToString()))
            {
                data.Datum = Convert.ToDateTime(row[DbEnumVeranstaltung.datum.ToString()].ToString());
            }
            else
            {
                data.Datum = null;
            }

            data.Name = row[DbEnumVeranstaltung.name.ToString()].ToString();
            data.Notiz = row[DbEnumVeranstaltung.notiz.ToString()].ToString();

            return data;
        }

        #endregion
    }
}